package com.ruifu.act.listener;

import lombok.Data;
import org.activiti.engine.ActivitiEngineAgenda;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityManager;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
import org.activiti.engine.runtime.Execution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component("multipleTaskCompleteListener")
@Data
public class MultipleTaskCompleteListener implements TaskListener {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    protected final String NUMBER_OF_INSTANCES = "nrOfInstances";
    protected final String NUMBER_OF_ACTIVE_INSTANCES = "nrOfActiveInstances";
    protected final String NUMBER_OF_COMPLETED_INSTANCES = "nrOfCompletedInstances";

    // 流程实例ID -> 已经分配的人员列表 (如果一个流程实例里面有多个多任务实例的情况，需要重新定义map的key)
    private Map<String, List<String>> processInstanceTaskIdsMap = new HashMap<>();

    @Override
    public void notify(DelegateTask delegateTask) {

        String message = (String) delegateTask.getVariable("message");

        //如果是多节点的驳回操作，这里需要进行减签
        if ("N".equals(message)) {
            //获取对应的manager工具类
            CommandContext cmmContext = Context.getCommandContext();
            ExecutionEntityManager exeEntityManager = cmmContext.getExecutionEntityManager();
            TaskEntityManager taskEntityManager = cmmContext.getTaskEntityManager();
            ActivitiEngineAgenda agenda = cmmContext.getAgenda();

            //当前进行驳回操作的任务节点（180001 -> 180006 -> *180024,180025*）
            ExecutionEntity executionEntity = (ExecutionEntity) runtimeService.createExecutionQuery()
                    .executionId(delegateTask.getExecutionId())
                    .singleResult();

            String parentId = executionEntity.getParentId();
            //二级父任务节点（180001 -> *180006* -> 180024,180025）
            ExecutionEntity parentExecution = executionEntity.getParent();
            parentExecution.getId();

            //获得的Execution是包括所有Execution和他们的父Execution，减签的时候要先删除子的才能删除父的实例
            List<Execution> executions = runtimeService.createExecutionQuery()
                    .processInstanceId(delegateTask.getProcessInstanceId())
                    .onlyChildExecutions()
                    .list();

            //获取所有该实例下的task任务
            List<TaskEntity> taskEntities = taskEntityManager.findTasksByProcessInstanceId(delegateTask.getProcessInstanceId());


            //1对当前驳回节点子实例的其他实例直接进行删除/完成操作
            for (Execution execution : executions) {
                if (!execution.getId().equals(parentId) && !execution.getId().equals(executionEntity.getId())) {
                    // System.out.println(execution.getParentId());
                    //runtimeService.deleteMultiInstanceExecution(execution.getId(),false);
                    //runtimeService.deleteProcessInstance(execution.getId(),"驳回，自动减签");

                    //1.1 删除所要删除的实例相关数据
                    exeEntityManager.deleteChildExecutions((ExecutionEntity) execution, "驳回，自动减签", false);

                    //1.2 获取二级执行实例关联的变量
                    //Integer nrOfInstances = (Integer) parentExecution.getVariable(NUMBER_OF_INSTANCES);
                    Integer nrOfActiveInstances = (Integer) parentExecution.getVariable(NUMBER_OF_ACTIVE_INSTANCES);
                    Integer nrOfCompletedInstances = (Integer) parentExecution.getVariable(NUMBER_OF_COMPLETED_INSTANCES);

                    //1.3 nrOfCompletedInstances 加 1，nrOfActiveInstances 减 1
                    parentExecution.setVariable(NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances + 1);
                    parentExecution.setVariableLocal(NUMBER_OF_ACTIVE_INSTANCES, nrOfActiveInstances - 1);
                }
            }

            //2 对当前任务之外的其他任务进行手动删除操作
            for (TaskEntity task : taskEntities) {
                if (!task.getId().equals(delegateTask.getId())) {
                    //cascade：true 进行级联删除task对应的历史任务
                    //cancel：true 删除任务的同时也会取消掉该任务
                    taskEntityManager.deleteTask(task, "驳回，自动减签任务", true, true);
                }

            }

            //3.触发当前执行的流程往下个节点运转wq
            //agenda.planContinueProcessInCompensation(executionEntity);

        }
    }
}
